package com.newcoin.xgb.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.newcoin.xgb.dto.BuyFinManDto;
import com.newcoin.xgb.dto.QueryParameterDto;
import com.newcoin.xgb.entity.*;
import com.newcoin.xgb.mapper.*;
import com.newcoin.xgb.po.FinancialOrderPo;
import com.newcoin.xgb.po.YebBalancePo;
import com.newcoin.xgb.service.YebService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class YebServiceImpl implements YebService {

    @Autowired
    private FinancialCycleMapper financialCycleMapper;

    @Autowired
    private FinOrderMapper finOrderMapper;

    @Autowired
    private AccountMapper accountMapper;

    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private FinancialProductMapper financialProductMapper;

    @Autowired
    private AssetRecordMapper assetRecordMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public Result<List<XgbFinancialProduct>> getFinMan() throws Exception {
        Result<List<XgbFinancialProduct>> result = new Result<>();
        List<XgbFinancialProduct> finMans = financialProductMapper.selectList(new QueryWrapper<XgbFinancialProduct>()
                .eq("cycle_id", 2));
        result.setData(finMans);
        result.setMessage("成功");
        result.setCode(200);
        return result;
    }

    @Override
    public Result<List<XgbFinancialProduct>> getFinancialProductList(Integer cycleId) throws Exception {
        Result<List<XgbFinancialProduct>> result = new Result<>();
        List<XgbFinancialProduct> list = financialProductMapper.selectList(new QueryWrapper<XgbFinancialProduct>()
                .eq("cycle_id", cycleId));
        result.setData(list);
        result.setCode(200);
        result.setMessage("成功");
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result buyFinMan(BuyFinManDto buyFinManDto) throws Exception {
        log.info("buyFinMan={}", buyFinManDto);
        Result<Boolean> result = new Result();
        if (loginVerification(buyFinManDto.getUserId(), buyFinManDto.getToken())) {
            result.setCode(401);
            result.setMessage("请登录");
            return result;
        }
        XgbUsers users = usersMapper.selectOne(new QueryWrapper<XgbUsers>()
                .eq("id", buyFinManDto.getUserId())
                .eq("pay_pwd", DigestUtils.md5DigestAsHex(buyFinManDto.getPayPwd().getBytes())));
        if (users == null) {
            result.setCode(500);
            result.setMessage("交易密码错误");
            return result;
        }
        XgbFinancialProduct financialProduct = financialProductMapper.selectById(buyFinManDto.getProductId());
        if (financialProduct.getEndAmount().compareTo(new BigDecimal("-1")) == 0) {
            if (buyFinManDto.getAmount().compareTo(financialProduct.getStartAmount()) < 0) {
                result.setCode(500);
                result.setMessage("该产品购买金额至少" + financialProduct.getStartAmount() + "USDT");
                return result;
            }
        } else {
            if (buyFinManDto.getAmount().compareTo(financialProduct.getStartAmount()) < 0
                    ||
                    buyFinManDto.getAmount().compareTo(financialProduct.getEndAmount()) >= 0) {
                result.setCode(500);
                result.setMessage("该产品购买金额在" + financialProduct.getStartAmount() + "-" + financialProduct.getEndAmount() + "USDT之间");
                return result;
            }
        }

        XgbAccount account = accountMapper.selectOne(new QueryWrapper<XgbAccount>().eq("user_id", buyFinManDto.getUserId()));
        if (account.getBalance().compareTo(buyFinManDto.getAmount()) < 0) {
            result.setCode(500);
            result.setMessage("余额不足");
            return result;
        }
        UpdateWrapper<XgbAccount> accountUpdateWrapper = new UpdateWrapper<>();
        accountUpdateWrapper.eq("user_id", buyFinManDto.getUserId()).setSql("balance=balance-" + buyFinManDto.getAmount()).setSql("financial_balance=financial_balance+" + buyFinManDto.getAmount());
        int row = accountMapper.update(null, accountUpdateWrapper);
        if (row != 1) {
            result.setCode(500);
            result.setMessage("购买失败");
            return result;
        }
        XgbFinancialCycle financialCycle = financialCycleMapper.selectById(financialProduct.getCycleId());
        XgbFinancialOrder financialOrder = new XgbFinancialOrder();
        financialOrder.setAmount(buyFinManDto.getAmount());
        financialOrder.setDay(financialCycle.getDay());
        financialOrder.setProductId(financialProduct.getId());
        financialOrder.setProportion(financialProduct.getDailyReleaseRatio());
        financialOrder.setUserId(buyFinManDto.getUserId());
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE, financialCycle.getDay());
        financialOrder.setEndDate(calendar.getTimeInMillis() / 1000);
        row = row + finOrderMapper.insert(financialOrder);
        if (row != 2) {
            throw new RuntimeException("购买失败");
        }
        XgbAssetRecord assetRecord = new XgbAssetRecord();
        assetRecord.setType(0);
        assetRecord.setAmount(buyFinManDto.getAmount());
        assetRecord.setName("购买理财产品");
        assetRecord.setUserId(buyFinManDto.getUserId());
        row = row + assetRecordMapper.insert(assetRecord);
        if (row != 3) {
            throw new RuntimeException("购买失败");
        }
        if (financialProduct.getLevel() > users.getLevel()) {
            row = row + usersMapper.update(null, new UpdateWrapper<XgbUsers>()
                    .eq("id", buyFinManDto.getUserId())
                    .set("level", financialProduct.getLevel()));
            if (row != 4) {
                throw new RuntimeException("购买失败");
            }
        }
        result.setMessage("转入成功");
        result.setCode(200);
        return result;
    }

    @Override
    public Result<YebBalancePo> getYebBalance(QueryParameterDto queryParameterDto) throws Exception {
        log.info("buyFinMan={}", queryParameterDto);
        Result<YebBalancePo> result = new Result();
        if (loginVerification(queryParameterDto.getUserId(), queryParameterDto.getToken())) {
            result.setCode(401);
            result.setMessage("请登录");
            return result;
        }
        XgbAccount account = accountMapper.selectOne(new QueryWrapper<XgbAccount>().eq("user_id", queryParameterDto.getUserId()));
        YebBalancePo yebBalancePo = new YebBalancePo();
        yebBalancePo.setBalance(account.getFinancialBalance());
        yebBalancePo.setIncome(account.getFinancialTotalIncome());
        yebBalancePo.setYesterdayIncome(account.getFinancialYesterdayTotalIncome());
        result.setCode(200);
        result.setMessage("成功");
        result.setData(yebBalancePo);
        return result;
    }

    @Override
    public Result<FinancialOrderPo> getFinancialOrderList(QueryParameterDto queryParameterDto) throws Exception {
        log.info("QueryParameterDto={}", queryParameterDto);
        Result<FinancialOrderPo> result = new Result();
        if (loginVerification(queryParameterDto.getUserId(), queryParameterDto.getToken())) {
            result.setCode(401);
            result.setMessage("请登录");
            return result;
        }
        Page<XgbFinancialOrder> page = new Page<>();
        page.setSize(10);
        page.setCurrent(queryParameterDto.getPage());
        IPage<XgbFinancialOrder> iPage = finOrderMapper.selectPage(page, new QueryWrapper<XgbFinancialOrder>()
                .eq("user_id", queryParameterDto.getUserId())
                .eq("state", 0)
                .orderByDesc("create_date"));
        FinancialOrderPo financialOrderPo = new FinancialOrderPo();
        financialOrderPo.setCurrentPage(iPage.getCurrent());
        financialOrderPo.setTotalPages(iPage.getPages());
        financialOrderPo.setList(iPage.getRecords());
        result.setMessage("成功");
        result.setCode(200);
        result.setData(financialOrderPo);
        return result;
    }

    @Override
    public Result<List<XgbFinancialCycle>> getCycleList() throws Exception {
        Result<List<XgbFinancialCycle>> result = new Result();
        List<XgbFinancialCycle> list = financialCycleMapper.selectList(new QueryWrapper<>());
        result.setData(list);
        result.setCode(200);
        result.setMessage("成功");
        return result;
    }


    private boolean loginVerification(Long userId, String token) {
        String redisToken = redisTemplate.opsForValue().get("token:" + userId);
        return (StringUtils.isEmpty(redisToken) || !redisToken.equalsIgnoreCase(token));
    }

}
